package com.csy.client_server.server_side;


import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.sql.SQLException;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.csy.mysql_util.MysqlUtil;
import com.csy.chat.getCurrent_time;
import com.csy.chat.chat_message;

class Server implements Runnable
{
    private static Map<String,Socket> map=new ConcurrentHashMap<>();
    private Socket socket;
    MysqlUtil all=new MysqlUtil();
    public Server(Socket socket)
    {
        this.socket=socket;
    }
    @Override
    public void run()
    {
        //获取客户端的输入流
        try
        {
            Scanner scanner=new Scanner(socket.getInputStream());
            String msg=null;
            while(true)
            {
                if(scanner.hasNextLine())
                {
                    //处理客户端输入的字符串
                    msg=scanner.nextLine();
                    Pattern pattern=Pattern.compile("\r");
                    Matcher matcher=pattern.matcher(msg);
                    msg=matcher.replaceAll("");
                    //注册用户流程,注册用户的格式为:userName:用户名
                    if(msg.startsWith("userName:"))
                    {
                        //将用户名保存在userName中
                        String userName=msg.split("\\:")[1];
                        System.out.println("**************"+userName);
                        //注册该用户
                        userRegist(userName,socket);
                        continue;
                    }
                    //群聊信息流程,群聊的格式为:G:群聊信息
                    else if(msg.startsWith("G:"))
                    {
                        //保存群聊信息
                        String str=msg.split("\\:")[1];
                        //发送群聊信息
                        groupChat(socket,str);
                        continue;
                    }
                    //私聊信息流程,私聊的格式为:P:userName-私聊信息
                    else if(msg.startsWith("P:")&&msg.contains("-"))
                    {
                        //保存需要私聊的用户名
                        String userName=msg.split("\\:")[1].split("-")[0];
                        //保存私聊的信息
                        String str=msg.split("\\:")[1].split("-")[1];
                        //发送私聊信息
                        privateChat(socket,userName,str);
                        continue;
                    }
                    //用户退出流程,用户退出格式为:包含exit
                    else if(msg.contains("exit"))
                    {
                        userExit(socket);
                        continue;
                    }
                }
            }
        }
        catch (IOException | SQLException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 注册用户信息
     * @param userName 用户名
     * @param socket 用户客户端Socket对象
     */
    private void userRegist(String userName,Socket socket) throws IOException {
        map.put(userName,socket);
        Set<Map.Entry<String,Socket>> set=map.entrySet();
        //遍历Set集合将群聊信息发给每一个客户端
        for(Map.Entry<String,Socket> entry:set)
        {
            //取得客户端的Socket对象
            Socket client=entry.getValue();
            //取得client客户端的输出流
            PrintStream printStream=new PrintStream(client.getOutputStream());
            printStream.println("~`");
            printStream.println("`当前在线人数为:"+set.size()+"人");
            for(Map.Entry<String,Socket> temp:set)
            {
                printStream.println("`"+temp.getKey());
            }
        }


        System.out.println("[用户名为"+userName+"][客户端为"+socket+"]上线了!");
        System.out.println("当前在线人数为:"+map.size()+"人");
    }

    /**
     * 群聊流程(将Map集合转换为Set集合,从而取得每个客户端Socket,将群聊信息发送给每个客户端)
     * @param socket 发出群聊的客户端
     * @param msg 群聊信息
     */
    private void groupChat(Socket socket,String msg) throws IOException, SQLException, ClassNotFoundException {
        getCurrent_time temp=new getCurrent_time();
        //将Map集合转换为Set集合
        Set<Map.Entry<String,Socket>> set=map.entrySet();
        //遍历Set集合找到发起群聊信息的用户
        String userName=null;
        for(Map.Entry<String,Socket> entry:set)
        {
            if(entry.getValue().equals(socket))
            {
                userName=entry.getKey();
                break;
            }
        }
        //遍历Set集合将群聊信息发给每一个客户端
        for(Map.Entry<String,Socket> entry:set)
        {
            //取得客户端的Socket对象
            Socket client=entry.getValue();
            //取得client客户端的输出流
            PrintStream printStream=new PrintStream(client.getOutputStream());
            StringBuffer tempTime=new StringBuffer(temp.getTime());
            printStream.println(tempTime);
            printStream.println(userName);
            printStream.println(msg);
        }
        all.set_chat_content(temp.getTime(),new StringBuffer(userName),msg);
    }
    /**
     * 私聊流程(利用userName取得客户端的Socket对象,从而取得对应输出流,将私聊信息发送到指定客户端)
     * @param socket 当前客户端
     * @param userName 私聊的用户名
     * @param msg 私聊的信息
     */
    private void privateChat(Socket socket,String userName,String msg) throws IOException
    {
        //取得当前客户端的用户名
        String curUser=null;
        Set<Map.Entry<String,Socket>> set=map.entrySet();
        for(Map.Entry<String,Socket> entry:set)
        {
            if(entry.getValue().equals(socket))
            {
                curUser=entry.getKey();
                break;
            }
        }
        //取得私聊用户名对应的客户端
        Socket client=map.get(userName);
        //获取私聊客户端的输出流,将私聊信息发送到指定客户端
        PrintStream printStream=new PrintStream(client.getOutputStream());
        printStream.println(curUser+"私聊说:"+msg);
    }

    /**
     * 用户退出
     * @param socket
     */
    private void userExit(Socket socket) throws IOException {
        //利用socket取得对应的Key值
        String userName=null;
        for(String key:map.keySet())
        {
            if(map.get(key).equals(socket))
            {
                userName=key;
                break;
            }
        }

        //将userName,Socket元素从map集合中删除
        map.remove(userName,socket);

        Set<Map.Entry<String,Socket>> set=map.entrySet();
        //遍历Set集合将群聊信息发给每一个客户端
        for(Map.Entry<String,Socket> entry:set)
        {
            //取得客户端的Socket对象
            Socket client=entry.getValue();
            //取得client客户端的输出流
            PrintStream printStream=new PrintStream(client.getOutputStream());
            printStream.println("~`");
            printStream.println("~当前在线人数为:"+set.size()+"人");
            for(Map.Entry<String,Socket> temp:set)
            {
                printStream.println("~"+temp.getKey());
            }
        }

        //提醒服务器该客户端已下线
        System.out.println("用户:"+userName+"已下线!");
        System.out.println("当前在线人数为:"+map.size()+"人");
    }
}
